package coin.yang.singleton;

public class SingletonDemo {

    public static void main(String[] args) {
        TaskManager2 t2 = TaskManager2.getInstance();
    }

}

// 单例模式
// 饿汉式 - 无论后续是否会使用这个对象，开始就将这个对象初始化
class TaskManager {

    private static TaskManager t = new TaskManager();

    // 只能对外提供唯一的一个实例的前提下，就不能在类外随意创建对象
    // 考虑将构造函数私有化
    private TaskManager() {
    }

    public static TaskManager getInstance() {
        return t;
    }

}

// 懒汉式 - 开始的时候不去实例化这个对象，而是在第一次使用的时候再初始化
// 如果多个线程同时调用getInstance方法，那么可能会出现线程的兵法安全问题
class TaskManager2 {

    private static TaskManager2 t = null;

    private TaskManager2() {
    }

    public static TaskManager2 getInstance() {
        // 判断t是否被初始化过
        if (t == null)
            t = new TaskManager2();
        return t;
    }

}

// 单重锁 - 解决了线程安全问题，但是
class TaskManager3 {

    private static TaskManager3 t = null;

    private TaskManager3() {
    }

    public static TaskManager3 getInstance() {
        // 将初始化过程加锁
        synchronized (TaskManager3.class) {
            // 判断t是否被初始化过
            if (t == null)
                t = new TaskManager3();
        }
        return t;
    }

}

// DCL - Double Check Lock
class TaskManager4 {

    // volatile的主要作用是禁止指令重排
    private static volatile TaskManager4 t = null;

    private TaskManager4() {
    }

    public static TaskManager4 getInstance() {
        if (t == null) {
            // 将初始化过程加锁
            synchronized (TaskManager4.class) {
                // 判断t是否被初始化过
                if (t == null)
                    t = new TaskManager4();
            }
        }
        return t;
    }

}

// 枚举式
enum TaskManager5 {
    // public static final TaskManager5 t = new TaskManager5();
    t
}

// 内部类式
class TaskManager6 {

    private TaskManager6() {
    }

    public static TaskManager6 getInstance() {
        return Instance.t;
    }

    private static class Instance {
        public static final TaskManager6 t = new TaskManager6();
    }

}